
package com.yimixian.app.cart;

import com.facebook.rebound.SimpleSpringListener;
import com.facebook.rebound.Spring;
import com.facebook.rebound.SpringConfig;
import com.umeng.analytics.MobclickAgent;
import com.yimixian.app.R;
import com.yimixian.app.SystemFramework;
import com.yimixian.app.common.CacheKeys;
import com.yimixian.app.common.Constants;
import com.yimixian.app.common.SharePreferenceKeys;
import com.yimixian.app.common.SpringCreator;
import com.yimixian.app.common.StatConstants;
import com.yimixian.app.data.DataManager;
import com.yimixian.app.model.Store;
import com.yimixian.app.util.GlobalLayoutUtils;
import com.yimixian.app.util.SharedPreferencesHelper;

import android.content.Context;
import android.graphics.Point;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.RelativeSizeSpan;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;

import butterknife.ButterKnife;
import butterknife.InjectView;

public class CartView extends FrameLayout {

    private static final SpringConfig LIST_SPRING_CONFIG = SpringConfig
            .fromOrigamiTensionAndFriction(50, 7);

    public interface Adapter {
        void onButtonClicked();

        BaseAdapter getCartListAdapter();
    }

    private enum State {
        LIST_HIDDEN,
        LIST_SHOWN,
        ANIMATING,
    }

    @InjectView(R.id.cart)
    FrameLayout mCart;
    @InjectView(R.id.goods_list)
    ListView mCartListView;
    @InjectView(R.id.bar_text)
    TextView mBarText;
    @InjectView(R.id.bar_button)
    TextView mBarButton;
    @InjectView(R.id.badge_number)
    TextView mBadgeNumber;
    @InjectView(R.id.touch_layer)
    View mTouchLayer;
    @InjectView(R.id.bar_background)
    View mBarBackgroundView;

    private DataManager mDataManager;
    private Spring mListSpring;
    private State mCurrentState;
    private Adapter mAdapter;
    private int mListHeight;
    private boolean mHasGoods;

    public CartView(Context context) {
        super(context);
        initCartView();
    }

    public CartView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initCartView();
    }

    public CartView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initCartView();
    }

    private void initCartView() {
        LayoutInflater.from(getContext()).inflate(R.layout.cart_view, this);
        ButterKnife.inject(this);
        mCart.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                MobclickAgent.onEvent(SystemFramework.getInstance().getGlobalContext(),
                        StatConstants.HOME_CART_CLICK);
                if (mHasGoods && mCurrentState == State.LIST_HIDDEN) {
                    // MobclickAgent.onEvent(this,
                    // StatConstants.HOME_CART_SHOW_CLICK);
                    showCartList();
                } else if (mCurrentState == State.LIST_SHOWN) {
                    hideCartList();
                }
            }
        });
        mBarButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                hideCartListWithoutAnimation();
                mAdapter.onButtonClicked();
            }
        });
        mDataManager = DataManager.getInstance();
        mCurrentState = State.LIST_HIDDEN;
        mListSpring = SpringCreator.create()
                .setSpringConfig(LIST_SPRING_CONFIG)
                .setOvershootClampingEnabled(true)
                .setCurrentValue(0)
                .setAtRest()
                .addListener(new ListSpringListener());

        mTouchLayer.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mCurrentState == State.LIST_SHOWN) {
                    hideCartList();
                }
            }
        });
    }

    public void setAllButtonsEnabled(boolean enabled) {
        mBarButton.setEnabled(enabled && mHasGoods);
        mCart.setEnabled(enabled);
    }

    public void setAdapter(Adapter adapter) {
        mAdapter = adapter;
    }

    public void setTotalPrice(float price) {
        if (price < 0.005) {
            mBarText.setVisibility(INVISIBLE);
        } else {
            mBarText.setVisibility(VISIBLE);
            SpannableStringBuilder builder = new SpannableStringBuilder("果品");
            builder.append(genPrice(price));
            builder.setSpan(new RelativeSizeSpan(1.4f), 2, builder.length(),
                    Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            Store store = SharedPreferencesHelper.getStore(SharePreferenceKeys.CURRENT_STORE);
            if (store != null) {
                float freeDeliveryPrice = (float) store.freeDeliveryPrice;
                if (price >= freeDeliveryPrice) {
                    builder
                            .append("元")
                            .append(Constants.SEPARATOR)
                            .append("配送费已免");
                } else {
                    builder
                            .append("元，配送费")
                            .append(genPrice((float) store.deliveryFee))
                            .append("元")
                            .append(Constants.SEPARATOR)
                            .append("差")
                            .append(genPrice(freeDeliveryPrice - price))
                            .append("元免配送费");
                }
            }
            mBarText.setText(builder);
        }
    }

    private String genPrice(float price) {
        String result = String.format("%.2f", price);
        while (result.substring(result.length() - 1).equals("0")) {
            result = result.substring(0, result.length() - 1);
        }
        if (result.substring(result.length() - 1).equals(".")) {
            result = result.substring(0, result.length() - 1);
        }
        return result;
    }

    public void setBadgeNumber(int number) {
        mBadgeNumber.setText(String.valueOf(number));
        mHasGoods = number > 0;
        mBadgeNumber.setVisibility(mHasGoods ? VISIBLE : INVISIBLE);
        mBarButton.setEnabled(mHasGoods);
    }

    public void showCartList() {
        if (mCurrentState != State.LIST_HIDDEN) {
            return;
        }

        mCurrentState = State.ANIMATING;
        mCartListView.setAdapter(mAdapter.getCartListAdapter());
        mCartListView.setVisibility(VISIBLE);
        mTouchLayer.setVisibility(VISIBLE);
        mTouchLayer.setAlpha(0f);

        GlobalLayoutUtils.runAfterSizedLayoutOfViewHierarchy(mCartListView, new Runnable() {
            @Override
            public void run() {
                mListHeight = mCartListView.getHeight();
                mCartListView.setTranslationY(mListHeight);
                mListSpring.setEndValue(1);
            }
        });
    }

    public void hideCartList() {
        if (mCurrentState != State.LIST_SHOWN) {
            return;
        }

        mCurrentState = State.ANIMATING;
        mListSpring.setEndValue(0);
    }

    public void hideCartListWithoutAnimation() {
        if (mCurrentState == State.LIST_HIDDEN) {
            return;
        }

        mListSpring.setCurrentValue(0);
        mCurrentState = State.LIST_HIDDEN;
        mCartListView.setAdapter(null);
        mCartListView.setVisibility(GONE);
        mTouchLayer.setVisibility(GONE);
    }

    public boolean isCartShown() {
        return mCurrentState == State.LIST_SHOWN;
    }

    // VALUE 0 -> LIST_HIDDEN,
    // VALUE 1 -> LIST_SHOWN
    private class ListSpringListener extends SimpleSpringListener {

        @Override
        public void onSpringUpdate(Spring spring) {
            onSpringMove(spring.getCurrentValue());
        }

        @Override
        public void onSpringAtRest(Spring spring) {
            if (spring.getCurrentValue() == 0) {
                mCurrentState = State.LIST_HIDDEN;
                mCartListView.setAdapter(null);
                mCartListView.setVisibility(GONE);
                mTouchLayer.setVisibility(GONE);
            } else if (spring.getCurrentValue() == 1) {
                mCurrentState = State.LIST_SHOWN;
            }
        }

        @Override
        public void onSpringActivate(Spring spring) {
            onSpringMove(spring.getCurrentValue());
        }

        private void onSpringMove(double value) {
            mCartListView.setTranslationY((float) ((1d - value) * mListHeight));
            mCart.setTranslationY((float) (-value * mListHeight));
            mTouchLayer.setAlpha((float) (.8 * value));
            mBarBackgroundView.setAlpha((float) (.85 + .15 * value));
        }
    }

    public ListView getCartListView() {
        return mCartListView;
    }

    public Point getCartLocationPoint() {
        int[] location = new int[2];
        mCart.getLocationInWindow(location);
        return new Point(location[0], location[1]);
    }
}
